{$I fbcc.inc}
unit uConfig;

interface

uses
  Windows,
  Classes,
  SysUtils,
  IniFiles;

type
  TConfigData = Class(TPersistent)
  private
    INI : TIniFile;
    FFileName : string;
    FTools    : TStringList;
    function GetShowTrayIcon: Boolean;
    procedure SetShowTrayIcon(const Value: Boolean);
    function GetTools: TStrings;
    procedure LoadTools;
    procedure SetTools(const Value: TStrings);
    function GetWinPos: TRect;
    procedure SetWinPos(const Value: TRect);
  protected
    procedure ToolsListChanged(Sender: TObject);
  public
    constructor Create; reintroduce;
    destructor Destroy; override;
  published
    property ShowTrayIcon : Boolean read GetShowTrayIcon write SetShowTrayIcon;
    property Tools: TStrings read GetTools Write SetTools;
    property WinPos : TRect read GetWinPos write SetWinPos;
  end;

function ConfigData : TConfigData;
function GetEnvVar(const Varname : string) : string;

implementation

uses
  FileCtrl,
  Forms,
  ShellLinks;

{------------------------------------------------------------}

var
  FConfigData : TConfigData;

function ConfigData : TConfigData;
begin
  if not Assigned(FConfigData) then FConfigData := TConfigData.Create;
  Result := FConfigData;
end;

function GetEnvVar(const Varname : string) : string;
var
  Len             : Integer;
begin
  Len := GetEnvironmentVariable(PChar(Varname), nil, 0);
  SetLength(Result, Len);
  Len := GetEnvironmentVariable(PChar(VarName), PChar(Result), Len);
  SetLength(Result, Len);
end;                                  { GetEnvVar }

{------------------------------------------------------------}

const
  SEC_GENERIC      = 'Generic';
  SEC_TOOLS        = 'Tools';
  SEC_WINPOS       = 'WinPos';

  VAR_COUNT        = 'Count';
  VAR_ITEM         = 'Item';
  VAR_SHOWTRAYICON = 'ShowTrayIcon';
  VAR_LEFT         = 'Left';
  VAR_TOP          = 'Top';
  VAR_RIGHT        = 'Right';
  VAR_BOTTOM       = 'Bottom';

{ TConfigData }

constructor TConfigData.Create;
var
  aDir : string;
  aName: string;
begin
  inherited Create;
  aName := ExtractFileName(Application.ExeName);
  aName := LowerCase(ChangeFileExt(aName, '.ini'));

  // store ini file in user appdata folder
//  aDir := SpecialDirectory(CSIDL_APPDATA);
  aDir := SpecialDirectory(CSIDL_PROFILE);
  if Length(aDir)>0 then begin
    aDir := IncludeTrailingBackslash(aDir) +
            '.firebird';
    if not DirectoryExists(aDir) then
      ForceDirectories(aDir);
  end
  else begin
    // not found? use application's folder
    aDir := ExtractFileDir(Application.ExeName)
  end;
  FTools := TStringList.Create;
  FTools.OnChange := ToolsListChanged;

  FFileName := IncludeTrailingBackslash(aDir) + aName;
  INI := TIniFile.Create(FFileName);
  LoadTools;
end;

destructor TConfigData.Destroy;
begin
  if Assigned(INI) then INI.UpdateFile;
  FreeAndNil(INI);
  FreeAndNil(FTools);
  inherited;
end;

function TConfigData.GetShowTrayIcon : Boolean;
begin
  Result := INI.ReadBool(SEC_GENERIC, VAR_SHOWTRAYICON, False);
end;

function TConfigData.GetTools: TStrings;
begin
  Result := FTools;
end;

function TConfigData.GetWinPos: TRect;
begin
  Result.Left   := INI.ReadInteger(SEC_WINPOS, VAR_Left, 0);
  Result.Top    := INI.ReadInteger(SEC_WINPOS, VAR_Top, 0);
  Result.Right  := INI.ReadInteger(SEC_WINPOS, VAR_Right, 0);
  Result.Bottom := INI.ReadInteger(SEC_WINPOS, VAR_Bottom, 0);
end;

procedure TConfigData.LoadTools;
var
  i,n : Integer;
  St  : string;
begin
  FTools.OnChange := nil;
  n := INI.ReadInteger(SEC_TOOLS, VAR_COUNT, 0);
  try
    FTools.Clear;
    for i := 0 to n-1 do begin
      St := INI.ReadString(SEC_TOOLS, VAR_ITEM+IntToStr(i), '');
      if Length(St) > 0 then
        FTools.Add(St);
    end;
  Finally
    FTools.OnChange := ToolsListChanged;
  end;
end;

procedure TConfigData.SetShowTrayIcon(const Value: Boolean);
begin
  INI.WriteBool(SEC_GENERIC, VAR_SHOWTRAYICON, Value);
end;

procedure TConfigData.SetTools(const Value: TStrings);
begin
  FTools.Assign(Value);
end;

procedure TConfigData.SetWinPos(const Value: TRect);
begin
  INI.WriteInteger(SEC_WINPOS, VAR_LEFT, Value.Left);
  INI.WriteInteger(SEC_WINPOS, VAR_TOP, Value.Top);
  INI.WriteInteger(SEC_WINPOS, VAR_Right, Value.Right);
  INI.WriteInteger(SEC_WINPOS, VAR_BOTTOM, Value.Bottom);
end;

procedure TConfigData.ToolsListChanged(Sender: TObject);
// the tools list has been changed. Reflect new list to ini file
var
  i : Integer;
begin
  if INI.SectionExists(SEC_TOOLS) then INI.EraseSection(SEC_TOOLS);
  INI.WriteInteger(SEC_TOOLS, VAR_COUNT, FTools.Count);
  for i := 0 to FTools.Count-1 do begin
    INI.WriteString(SEC_TOOLS, VAR_ITEM+IntToStr(i), FTools.Strings[i]);
  end;
end;

Initialization
  FConfigData := nil;

Finalization
  FreeAndNil(FConfigData);
end.
